﻿using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using CkSoftware.GroupMe.Sdk.Core;
using CkSoftware.GroupMe.Sdk.Core.Dao;
using CkSoftware.GroupMe.Sdk.Groups.Dao;

namespace CkSoftware.GroupMe.Sdk.Groups.Commands
{
	/// <summary>
	/// Group add member command (GroupMe documentation: <see href="https://dev.groupme.com/docs/v3#members_add" />).
	/// </summary>
	public class GroupAddMemberCommand : IWebApiCommand<GroupMeApiResponse<AsyncGroupMeApiResult>>
	{
		private const string CommandNameFormat = "/groups/{0}/members/add";
		private readonly List<AddMemberData> _addedMembers;
		private readonly string _groupId;
		private readonly GroupAddMemberParameters _parameters;

		/// <summary>
		/// Instantiate a new <see cref="GroupAddMemberCommand" /> for the given group id.
		/// </summary>
		/// <param name="groupId">The group id in which the members should be added.</param>
		public GroupAddMemberCommand(string groupId)
		{
			_groupId = groupId;
			_addedMembers = new List<AddMemberData>();
			_parameters = new GroupAddMemberParameters();
		}

		/// <summary>
		/// Provides a list of the members which will be added on command-execution.
		/// </summary>
		public IEnumerable<AddMemberData> AddedMembers
		{
			get { return _addedMembers; }
		}

		/// <summary>
		/// Defines if the command is executed once.
		/// </summary>
		public bool CommandExecuted { get; set; }

		/// <summary>
		/// The name of the command to be executed.
		/// </summary>
		public string CommandName
		{
			get { return string.Format(CultureInfo.CurrentCulture, CommandNameFormat, _groupId); }
		}

		/// <summary>
		/// The http method to execute this command.
		/// </summary>
		public HttpMethod HttpMethod
		{
			get { return HttpMethod.Post; }
		}

		/// <summary>
		/// The parameters which should be used on command execution.
		/// </summary>
		public IWebApiCommandParameters Parameters
		{
			get { return _parameters; }
		}

		/// <summary>
		/// Adds a member to the list of members-to-add. Will be added to the group on command execution.
		/// </summary>
		/// <param name="nickname">The nickname the user will have in this group initially.</param>
		/// <param name="userId">The userId of the member to add. Either userId, phoneNumber or email must be added but not all of it.</param>
		/// <param name="phoneNumber">The phone number of the user. Either userId, phoneNumber or email must be added but not all of it.</param>
		/// <param name="email">The email address of the user. Either userId, phoneNumber or email must be added but not all of it.</param>
		/// <returns>The extended <see cref="GroupAddMemberCommand" />.</returns>
		public GroupAddMemberCommand WithMember(string nickname,
			string userId = "",
			string phoneNumber = "",
			string email = "")
		{
			AddMemberData addedMember = _parameters.AddMember(new AddMemberData
			{
				Nickname = nickname,
				UserId = userId,
				PhoneNumber = phoneNumber,
				Email = email
			});

			_addedMembers.Add(addedMember);

			return this;
		}
	}
}